package edu.winona.csclub.testing.generators;

import java.util.*;

import edu.winona.csclub.testing.core.*;

/**
 * Uses boundary value analysis methods to generate test cases
 * <p><b>Normal (4n+1)</b>: min, min+, max-, and max of every variable (all other variables nom), plus a test with all nom
 * <br><b>Robust (6n+1)</b>: min-, min, min+, max-, max, and max+ of every variable (all other variables nom), plus a test with all nom
 * 
 * @author Matthew Lieder
 */
public class BoundaryValue implements EnumProvider {
	
	private boolean robust = false;
	
	/**
	 * Creates a new BoundaryValue instance using Normal or Robust BVA
	 */	
	public BoundaryValue(boolean robust) {
		this.robust = robust;
	}

	public void generateTests(Command command, TestCase tests) {
		List<Variable> vars = command.getVariables();
		
		// generate 4n/6n tests (depending if it's Normal or Robust)
		for(Variable var: vars) {
			List<Value> singleVarValues = new LinkedList<Value>();
			
			if(robust) singleVarValues.add(new Value(var, "" + (var.getRange()[0].getMin() - 1))); // min-
			singleVarValues.add(new Value(var, "" + (var.getRange()[0].getMin()))); // min
			singleVarValues.add(new Value(var, "" + (var.getRange()[0].getMin() + 1))); // min+
			
			singleVarValues.add(new Value(var, "" + (var.getRange()[0].getMax() - 1))); // max-
			singleVarValues.add(new Value(var, "" + (var.getRange()[0].getMax()))); // max
			if(robust) singleVarValues.add(new Value(var, "" + (var.getRange()[0].getMax() + 1))); // max+
			
			// create tests using all the above values of the variable,
			// with all other variables set to nom
			for(Value val: singleVarValues) {
				// select one value for this variable
				List<Value> values = new LinkedList<Value>();
				values.add(val);
				
				// get the nom values of all the other variables
				for(Variable otherVar: vars)
					if(otherVar != var)
						values.add(new Value(otherVar, "" + otherVar.getRange()[0].getNom())); // nom
				
				// put them all together in a new test
				tests.addTest(new Test(command, values));
			}
		}
		
		// don't forget to generate the +1 test (all variables at nom)!
		List<Value> values = new LinkedList<Value>();
		for(Variable var: vars)
			values.add(new Value(var, "" + var.getRange()[0].getNom())); // nom
		tests.addTest(new Test(command, values));
	}
}